package com.yunke.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yunke.common.exception.YunkeAssert;
import com.yunke.common.exception.YunkeException;
import com.yunke.common.result.YunkeResultCode;
import com.yunke.common.security.YunkeSecurityUtil;
import com.yunke.common.util.YunkeInviteCodeUtil;
import com.yunke.common.util.YunkePasswordUtil;
import com.yunke.common.util.YunkeTimeUtil;
import com.yunke.dto.user.YunkeUserProfileDto;
import com.yunke.entity.YunkeUser;
import com.yunke.mapper.YunkeUserMapper;
import com.yunke.mapper.YunkeUserTokenMapper;
import com.yunke.service.YunkeSmsService;
import com.yunke.service.YunkeUserService;
import com.yunke.vo.user.YunkeUserCenterVo;
import com.yunke.vo.user.YunkeUserInfoVo;
import com.yunke.vo.user.YunkeUserLoginVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import jakarta.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 用户Service实现类
 * 
 * @author yunke
 * @since 1.0.0
 */
@Slf4j
@Service
public class YunkeUserServiceImpl extends ServiceImpl<YunkeUserMapper, YunkeUser> implements YunkeUserService {

    @Autowired
    private YunkeUserMapper userMapper;

    @Autowired
    private YunkeUserTokenMapper userTokenMapper;

    @Autowired
    private YunkeSmsService smsService;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 短信验证码Redis Key前缀
     */
    private static final String SMS_CODE_PREFIX = "yunke:sms:code:";

    /**
     * 短信发送频率控制Redis Key前缀
     */
    private static final String SMS_SEND_LIMIT_PREFIX = "yunke:sms:limit:";

    /**
     * 默认密码（当用户使用短信验证码注册时）
     */
    private static final String DEFAULT_PASSWORD = "123456";

    @Override
    public boolean sendSmsCode(String phone, Integer type) {
        log.info("发送短信验证码: phone={}, type={}", phone, type);
        
        // 验证手机号格式
        YunkeAssert.isTrue(isValidPhone(phone), YunkeResultCode.USER_PHONE_EXIST);
        
        // 检查发送频率
        String limitKey = SMS_SEND_LIMIT_PREFIX + phone + ":" + type;
        Boolean hasLimit = redisTemplate.hasKey(limitKey);
        YunkeAssert.isFalse(Boolean.TRUE.equals(hasLimit), YunkeResultCode.SMS_SEND_FAIL, "发送过于频繁，请60秒后再试");
        
        // 生成验证码
        String code = generateSmsCode();
        
        // 发送短信
        boolean sendResult = smsService.sendSmsCode(phone, code, type);
        YunkeAssert.isTrue(sendResult, YunkeResultCode.SMS_SEND_FAIL);
        
        // 缓存验证码（5分钟过期）
        String codeKey = SMS_CODE_PREFIX + phone + ":" + type;
        redisTemplate.opsForValue().set(codeKey, code, 300);
        
        // 设置发送频率限制（60秒）
        redisTemplate.opsForValue().set(limitKey, "1", 60);
        
        log.info("短信验证码发送成功: phone={}, code={}", phone, code);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean register(String phone, String smsCode, String password, String inviteCode) {
        log.info("用户注册: phone={}, hasPassword={}, inviteCode={}", phone, StringUtils.hasText(password), inviteCode);
        
        // 验证手机号格式
        YunkeAssert.isTrue(isValidPhone(phone), YunkeResultCode.USER_PHONE_EXIST);
        
        // 验证短信验证码
        verifySmsCode(phone, smsCode, 1);
        
        // 检查用户是否已存在
        YunkeUser existUser = getUserByPhone(phone);
        YunkeAssert.isNull(existUser, YunkeResultCode.USER_ALREADY_EXIST);
        
        // 验证密码格式（如果提供了密码）
        if (StringUtils.hasText(password)) {
            YunkeAssert.isTrue(YunkePasswordUtil.isValidPassword(password), YunkeResultCode.USER_PASSWORD_ERROR);
        }
        
        // 验证邀请码（如果提供了邀请码）
        YunkeUser inviteUser = null;
        if (StringUtils.hasText(inviteCode)) {
            inviteUser = getUserByInviteCode(inviteCode);
            YunkeAssert.notNull(inviteUser, YunkeResultCode.USER_NOT_EXIST, "邀请码不存在");
        }
        
        // 创建用户
        YunkeUser user = new YunkeUser();
        user.setPhone(phone);
        user.setNickname("用户" + phone.substring(7)); // 默认昵称
        user.setSex(1); // 默认男性
        user.setStatus(1); // 启用状态
        user.setBalance(BigDecimal.ZERO);
        user.setLevelId(1L); // 默认等级
        user.setLevelName("普通用户");
        user.setIsAuthentication(0); // 未认证
        user.setIsOnline(1); // 在线
        user.setDisable(1); // 启用
        
        // 设置密码
        if (StringUtils.hasText(password)) {
            user.setRealName(YunkePasswordUtil.encode(password));
        } else {
            user.setRealName(YunkePasswordUtil.encode(DEFAULT_PASSWORD));
        }
        
        // 生成唯一邀请码
        String userInviteCode = generateUniqueInviteCode();
        user.setInviteCode(userInviteCode);
        
        // 设置上级关系
        if (inviteUser != null) {
            user.setPid(inviteUser.getId());
            user.setPids(inviteUser.getPids() + "," + inviteUser.getId());
        } else {
            user.setPid(0L);
            user.setPids("0");
        }
        
        // 设置注册信息
        String registerIp = getClientIp();
        user.setRegisterIp(registerIp);
        user.setLastLoginIp(registerIp);
        
        // 设置时间
        long currentTime = System.currentTimeMillis();
        user.setCreateTime(YunkeTimeUtil.timestampToLocalDateTime(currentTime));
        user.setUpdateTime(YunkeTimeUtil.timestampToLocalDateTime(currentTime));
        user.setLastLoginTime(currentTime);
        
        // 保存用户
        boolean saveResult = save(user);
        YunkeAssert.isTrue(saveResult, YunkeResultCode.USER_REGISTER_FAIL);
        
        // 删除验证码缓存
        String codeKey = SMS_CODE_PREFIX + phone + ":1";
        redisTemplate.delete(codeKey);
        
        log.info("用户注册成功: userId={}, phone={}", user.getId(), phone);
        return true;
    }

    @Override
    public YunkeUserLoginVo login(String username, String password) {
        log.info("密码登录: username={}", username);
        
        // 验证用户名格式（支持手机号）
        YunkeAssert.isTrue(isValidPhone(username), YunkeResultCode.USER_PHONE_EXIST);
        YunkeAssert.hasText(password, YunkeResultCode.PARAM_ERROR, "密码不能为空");
        
        // 查询用户
        YunkeUser user = getUserByPhone(username);
        YunkeAssert.notNull(user, YunkeResultCode.USER_NOT_EXIST);
        
        // 检查用户状态
        YunkeAssert.isTrue(user.getStatus() == 1, YunkeResultCode.USER_DISABLED);
        YunkeAssert.isTrue(user.getDisable() == 1, YunkeResultCode.USER_DISABLED);
        
        // 验证密码
        YunkeAssert.isTrue(YunkePasswordUtil.matches(password, user.getRealName()), 
                          YunkeResultCode.USER_PASSWORD_ERROR);
        
        // 执行登录
        String token = performLogin(user);
        
        // 构建登录结果
        YunkeUserLoginVo loginVo = new YunkeUserLoginVo();
        loginVo.setToken(token);
        loginVo.setUserId(user.getId());
        loginVo.setUsername(user.getUsername());
        loginVo.setNickname(user.getNickname());
        loginVo.setAvatar(user.getAvatar());
        loginVo.setPhone(user.getPhone());
        loginVo.setVipLevel(user.getVipLevel());
        loginVo.setIsAuth(user.getIsAuth());
        
        return loginVo;
    }

    @Override
    public YunkeUserLoginVo smsLogin(String phone, String smsCode) {
        log.info("短信验证码登录: phone={}", phone);
        
        // 验证手机号格式
        YunkeAssert.isTrue(isValidPhone(phone), YunkeResultCode.USER_PHONE_EXIST);
        
        // 验证短信验证码
        verifySmsCode(phone, smsCode, 2);
        
        // 查询用户
        YunkeUser user = getUserByPhone(phone);
        YunkeAssert.notNull(user, YunkeResultCode.USER_NOT_EXIST);
        
        // 检查用户状态
        YunkeAssert.isTrue(user.getStatus() == 1, YunkeResultCode.USER_DISABLED);
        YunkeAssert.isTrue(user.getDisable() == 1, YunkeResultCode.USER_DISABLED);
        
        // 删除验证码缓存
        String codeKey = SMS_CODE_PREFIX + phone + ":2";
        redisTemplate.delete(codeKey);
        
        // 执行登录
        String token = performLogin(user);
        
        // 构建登录结果
        YunkeUserLoginVo loginVo = new YunkeUserLoginVo();
        loginVo.setToken(token);
        loginVo.setUserId(user.getId());
        loginVo.setUsername(user.getUsername());
        loginVo.setNickname(user.getNickname());
        loginVo.setAvatar(user.getAvatar());
        loginVo.setPhone(user.getPhone());
        loginVo.setVipLevel(user.getVipLevel());
        loginVo.setIsAuth(user.getIsAuth());
        
        return loginVo;
    }

    /**
     * 执行登录操作
     */
    private String performLogin(YunkeUser user) {
        // 使用Sa-Token进行登录
        YunkeSecurityUtil.login(user.getId());
        
        // 更新最后登录信息
        updateLastLoginInfo(user.getId(), getClientIp());
        
        // 返回Token
        String token = YunkeSecurityUtil.getToken();
        log.info("用户登录成功: userId={}, token={}", user.getId(), token);
        return token;
    }

    /**
     * 验证短信验证码
     */
    private void verifySmsCode(String phone, String smsCode, Integer type) {
        YunkeAssert.hasText(smsCode, YunkeResultCode.PARAM_ERROR, "短信验证码不能为空");
        
        String codeKey = SMS_CODE_PREFIX + phone + ":" + type;
        String cachedCode = (String) redisTemplate.opsForValue().get(codeKey);
        
        YunkeAssert.hasText(cachedCode, YunkeResultCode.SMS_CODE_EXPIRED);
        YunkeAssert.isTrue(smsCode.equals(cachedCode), YunkeResultCode.SMS_CODE_ERROR);
    }

    /**
     * 生成短信验证码
     */
    private String generateSmsCode() {
        return String.valueOf((int) ((Math.random() + 1) * 100000));
    }

    /**
     * 生成唯一邀请码
     */
    private String generateUniqueInviteCode() {
        String inviteCode;
        int maxRetry = 10;
        int retry = 0;
        
        do {
            inviteCode = YunkeInviteCodeUtil.generateInviteCode();
            retry++;
        } while (getUserByInviteCode(inviteCode) != null && retry < maxRetry);
        
        YunkeAssert.isTrue(retry < maxRetry, YunkeResultCode.SYSTEM_ERROR, "生成邀请码失败");
        return inviteCode;
    }

    /**
     * 验证手机号格式
     */
    private boolean isValidPhone(String phone) {
        return StringUtils.hasText(phone) && phone.matches("^1[3-9]\\d{9}$");
    }

    /**
     * 获取客户端IP
     */
    private String getClientIp() {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes != null) {
            HttpServletRequest request = attributes.getRequest();
            String xForwardedFor = request.getHeader("X-Forwarded-For");
            if (StringUtils.hasText(xForwardedFor)) {
                return xForwardedFor.split(",")[0].trim();
            }
            return request.getRemoteAddr();
        }
        return "127.0.0.1";
    }

    @Override
    public YunkeUser getUserByPhone(String phone) {
        if (!StringUtils.hasText(phone)) {
            return null;
        }
        
        LambdaQueryWrapper<YunkeUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(YunkeUser::getPhone, phone);
        return getOne(wrapper);
    }

    @Override
    public YunkeUser getUserByInviteCode(String inviteCode) {
        if (!StringUtils.hasText(inviteCode)) {
            return null;
        }
        
        LambdaQueryWrapper<YunkeUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(YunkeUser::getInviteCode, inviteCode);
        return getOne(wrapper);
    }

    @Override
    public String generateInviteCode() {
        return generateUniqueInviteCode();
    }

    @Override
    public boolean checkUserExists(String phone) {
        return getUserByPhone(phone) != null;
    }

    @Override
    public void updateLastLoginInfo(Long userId, String loginIp) {
        YunkeUser user = new YunkeUser();
        user.setId(userId);
        user.setLastLoginIp(loginIp);
        user.setLastLoginTime(System.currentTimeMillis());
        user.setIsOnline(1);
        user.setUpdateTime(YunkeTimeUtil.timestampToLocalDateTime(System.currentTimeMillis()));
        updateById(user);
    }

    // 其他方法将在下一个提交中继续实现...
    
    @Override
    public String wechatLogin(String code, String inviteCode) {
        YunkeUserLoginVo result = wechatLoginWithResult(code, inviteCode);
        return result.getToken();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public YunkeUserLoginVo wechatLoginWithResult(String code, String inviteCode) {
        log.info("微信登录: code={}, inviteCode={}", code, inviteCode);
        
        // 参数验证
        YunkeAssert.hasText(code, YunkeResultCode.PARAM_ERROR, "微信授权码不能为空");
        
        try {
            // TODO: 调用微信API获取用户信息
            // 这里模拟微信API调用
            String openId = "mock_openid_" + System.currentTimeMillis();
            String unionId = "mock_unionid_" + System.currentTimeMillis();
            String nickname = "微信用户" + System.currentTimeMillis() % 10000;
            String avatar = "https://thirdwx.qlogo.cn/mmopen/mock/avatar.jpg";
            
            // 查询是否已存在该微信用户
            YunkeUser existUser = userMapper.selectOne(
                new LambdaQueryWrapper<YunkeUser>()
                    .eq(YunkeUser::getUserGzhId, openId.hashCode() & 0x7fffffff)
                    .or()
                    .eq(YunkeUser::getUserXcxId, openId.hashCode() & 0x7fffffff)
            );
            
            YunkeUser user;
            if (existUser != null) {
                // 已存在用户，更新登录信息
                user = existUser;
                user.setLastLoginTime(System.currentTimeMillis());
                user.setLastLoginIp(getClientIp());
                user.setUpdateTime(YunkeTimeUtil.timestampToLocalDateTime(System.currentTimeMillis()));
                updateById(user);
                log.info("微信用户已存在，直接登录: userId={}", user.getId());
            } else {
                // 新用户，创建账户
                user = new YunkeUser();
                user.setNickname(nickname);
                user.setAvatar(avatar);
                user.setUserGzhId(Long.valueOf(openId.hashCode() & 0x7fffffff)); // 模拟openId转换
                user.setInviteCode(generateUniqueInviteCode());
                user.setStatus(1); // 启用状态
                user.setLastLoginTime(System.currentTimeMillis());
                user.setLastLoginIp(getClientIp());
                user.setRegisterIp(getClientIp());
                user.setUpdateTime(YunkeTimeUtil.timestampToLocalDateTime(System.currentTimeMillis()));
                
                // 处理邀请码
                if (StringUtils.hasText(inviteCode)) {
                    YunkeUser inviteUser = getUserByInviteCode(inviteCode);
                    if (inviteUser != null) {
                        user.setPid(inviteUser.getId());
                        user.setPids(inviteUser.getPids() + "," + inviteUser.getId());
                        log.info("微信注册使用邀请码: inviteCode={}, inviteUserId={}", inviteCode, inviteUser.getId());
                    }
                }
                
                save(user);
                log.info("微信新用户注册成功: userId={}, nickname={}", user.getId(), nickname);
            }
            
            // 生成JWT Token
            String token = performLogin(user);
            
            // 构建返回结果
            YunkeUserLoginVo loginVo = new YunkeUserLoginVo();
            loginVo.setUserId(user.getId());
            loginVo.setUsername(user.getNickname());
            loginVo.setNickname(user.getNickname());
            loginVo.setAvatar(user.getAvatar());
            loginVo.setPhone(user.getPhone());
            loginVo.setToken(token);
            loginVo.setIsNewUser(existUser == null);
            
            log.info("微信登录成功: userId={}, isNewUser={}", user.getId(), existUser == null);
            return loginVo;
            
        } catch (Exception e) {
            log.error("微信登录失败: code={}, error={}", code, e.getMessage(), e);
            throw new YunkeException(YunkeResultCode.SYSTEM_ERROR, "微信登录失败：" + e.getMessage());
        }
    }

    @Override
    public boolean logout() {
        try {
            // 用户退出登录
            YunkeSecurityUtil.logout();
            
            // 更新用户在线状态
            if (YunkeSecurityUtil.isLogin()) {
                Long userId = YunkeSecurityUtil.getCurrentUserId();
                YunkeUser user = new YunkeUser();
                user.setId(userId);
                user.setIsOnline(0); // 离线
                user.setUpdateTime(YunkeTimeUtil.timestampToLocalDateTime(System.currentTimeMillis()));
                updateById(user);
            }
            
            log.info("用户退出登录成功");
            return true;
        } catch (Exception e) {
            log.error("用户退出登录失败: {}", e.getMessage());
            return false;
        }
    }

    @Override
    public String refreshToken() {
        // 检查当前是否已登录
        YunkeAssert.isTrue(YunkeSecurityUtil.isLogin(), YunkeResultCode.USER_NOT_LOGIN);
        
        // 续签Token（延长30天）
        YunkeSecurityUtil.renewTimeout(2592000);
        
        // 返回新的Token
        String newToken = YunkeSecurityUtil.getToken();
        log.info("Token刷新成功: userId={}", YunkeSecurityUtil.getCurrentUserId());
        return newToken;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean forgetPassword(String phone, String smsCode, String newPassword) {
        log.info("忘记密码: phone={}", phone);
        
        // 验证手机号格式
        YunkeAssert.isTrue(isValidPhone(phone), YunkeResultCode.USER_PHONE_EXIST);
        YunkeAssert.hasText(newPassword, YunkeResultCode.PARAM_ERROR, "新密码不能为空");
        
        // 验证新密码格式
        YunkeAssert.isTrue(YunkePasswordUtil.isValidPassword(newPassword), YunkeResultCode.USER_PASSWORD_ERROR);
        
        // 验证短信验证码
        verifySmsCode(phone, smsCode, 3);
        
        // 查询用户
        YunkeUser user = getUserByPhone(phone);
        YunkeAssert.notNull(user, YunkeResultCode.USER_NOT_EXIST);
        
        // 更新密码
        user.setRealName(YunkePasswordUtil.encode(newPassword));
        user.setUpdateTime(YunkeTimeUtil.timestampToLocalDateTime(System.currentTimeMillis()));
        boolean updateResult = updateById(user);
        
        // 删除验证码缓存
        String codeKey = SMS_CODE_PREFIX + phone + ":3";
        redisTemplate.delete(codeKey);
        
        log.info("忘记密码重置成功: userId={}", user.getId());
        return updateResult;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean changePassword(String oldPassword, String newPassword) {
        log.info("修改密码: userId={}", YunkeSecurityUtil.getCurrentUserId());
        
        // 检查登录状态
        YunkeSecurityUtil.checkLogin();
        
        // 参数验证
        YunkeAssert.hasText(oldPassword, YunkeResultCode.PARAM_ERROR, "旧密码不能为空");
        YunkeAssert.hasText(newPassword, YunkeResultCode.PARAM_ERROR, "新密码不能为空");
        YunkeAssert.isTrue(YunkePasswordUtil.isValidPassword(newPassword), YunkeResultCode.USER_PASSWORD_ERROR);
        
        // 获取当前用户
        Long userId = YunkeSecurityUtil.getCurrentUserId();
        YunkeUser user = getById(userId);
        YunkeAssert.notNull(user, YunkeResultCode.USER_NOT_EXIST);
        
        // 验证旧密码
        YunkeAssert.isTrue(YunkePasswordUtil.matches(oldPassword, user.getRealName()), 
                          YunkeResultCode.USER_OLD_PASSWORD_ERROR);
        
        // 检查新旧密码是否相同
        YunkeAssert.isFalse(oldPassword.equals(newPassword), YunkeResultCode.PARAM_ERROR, "新密码不能与旧密码相同");
        
        // 更新密码
        user.setRealName(YunkePasswordUtil.encode(newPassword));
        user.setUpdateTime(YunkeTimeUtil.timestampToLocalDateTime(System.currentTimeMillis()));
        boolean updateResult = updateById(user);
        
        log.info("修改密码成功: userId={}", userId);
        return updateResult;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean bindPhone(String phone, String smsCode) {
        log.info("绑定手机号: phone={}", phone);
        
        // 检查登录状态
        YunkeSecurityUtil.checkLogin();
        
        // 验证手机号格式
        YunkeAssert.isTrue(isValidPhone(phone), YunkeResultCode.USER_PHONE_EXIST);
        
        // 验证短信验证码
        verifySmsCode(phone, smsCode, 4);
        
        // 检查手机号是否已被其他用户使用
        YunkeUser existUser = getUserByPhone(phone);
        YunkeAssert.isNull(existUser, YunkeResultCode.USER_PHONE_EXIST, "手机号已被其他用户使用");
        
        // 获取当前用户
        Long userId = YunkeSecurityUtil.getCurrentUserId();
        YunkeUser user = getById(userId);
        YunkeAssert.notNull(user, YunkeResultCode.USER_NOT_EXIST);
        
        // 检查是否已经绑定手机号
        YunkeAssert.isFalse(StringUtils.hasText(user.getPhone()), YunkeResultCode.USER_PHONE_EXIST, "已绑定手机号，请先解绑");
        
        // 绑定手机号
        user.setPhone(phone);
        user.setUpdateTime(YunkeTimeUtil.timestampToLocalDateTime(System.currentTimeMillis()));
        boolean updateResult = updateById(user);
        
        // 删除验证码缓存
        String codeKey = SMS_CODE_PREFIX + phone + ":4";
        redisTemplate.delete(codeKey);
        
        log.info("绑定手机号成功: userId={}, phone={}", userId, phone);
        return updateResult;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean unbindPhone(String smsCode) {
        log.info("解绑手机号: userId={}", YunkeSecurityUtil.getCurrentUserId());
        
        // 检查登录状态
        YunkeSecurityUtil.checkLogin();
        
        // 获取当前用户
        Long userId = YunkeSecurityUtil.getCurrentUserId();
        YunkeUser user = getById(userId);
        YunkeAssert.notNull(user, YunkeResultCode.USER_NOT_EXIST);
        YunkeAssert.hasText(user.getPhone(), YunkeResultCode.PARAM_ERROR, "未绑定手机号");
        
        // 验证短信验证码
        verifySmsCode(user.getPhone(), smsCode, 5);
        
        // 解绑手机号
        user.setPhone("");
        user.setUpdateTime(YunkeTimeUtil.timestampToLocalDateTime(System.currentTimeMillis()));
        boolean updateResult = updateById(user);
        
        // 删除验证码缓存
        String codeKey = SMS_CODE_PREFIX + user.getPhone() + ":5";
        redisTemplate.delete(codeKey);
        
        log.info("解绑手机号成功: userId={}", userId);
        return updateResult;
    }

    @Override
    public YunkeUserInfoVo getCurrentUserInfo() {
        // 检查登录状态
        YunkeSecurityUtil.checkLogin();
        
        // 获取当前用户ID
        Long userId = YunkeSecurityUtil.getCurrentUserId();
        
        // 查询用户信息
        YunkeUser user = getById(userId);
        YunkeAssert.notNull(user, YunkeResultCode.USER_NOT_EXIST);
        
        // 转换为VO
        YunkeUserInfoVo userInfoVo = new YunkeUserInfoVo();
        userInfoVo.setId(user.getId());
        userInfoVo.setUsername(user.getUsername());
        userInfoVo.setPhone(user.getPhone());
        userInfoVo.setNickname(user.getNickname());
        userInfoVo.setAvatar(user.getAvatar());
        userInfoVo.setGender(user.getGender());
        userInfoVo.setAge(user.getAge());
        userInfoVo.setSignature(user.getSignature());
        userInfoVo.setVipLevel(user.getVipLevel());
        userInfoVo.setInviteCode(user.getInviteCode());
        userInfoVo.setIsAuth(user.getIsAuth());
        userInfoVo.setCreateTime(user.getCreateTime());
        userInfoVo.setLastLoginTime(YunkeTimeUtil.timestampToLocalDateTime(user.getLastLoginTime()));
        
        log.info("获取用户信息成功: userId={}", userId);
        return userInfoVo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateUserInfo(YunkeUserInfoVo userInfo) {
        // 检查登录状态
        YunkeSecurityUtil.checkLogin();
        
        // 获取当前用户ID
        Long userId = YunkeSecurityUtil.getCurrentUserId();
        log.info("更新用户信息: userId={}", userId);
        
        // 查询当前用户
        YunkeUser user = getById(userId);
        YunkeAssert.notNull(user, YunkeResultCode.USER_NOT_EXIST);
        
        // 更新用户信息
        if (StringUtils.hasText(userInfo.getNickname())) {
            user.setNickname(userInfo.getNickname());
        }
        if (StringUtils.hasText(userInfo.getAvatar())) {
            user.setAvatar(userInfo.getAvatar());
        }
        if (userInfo.getGender() != null) {
            user.setGender(userInfo.getGender());
        }
        if (userInfo.getAge() != null) {
            user.setAge(userInfo.getAge());
        }
        if (StringUtils.hasText(userInfo.getSignature())) {
            user.setSignature(userInfo.getSignature());
        }
        
        user.setUpdateTime(YunkeTimeUtil.timestampToLocalDateTime(System.currentTimeMillis()));
        boolean updateResult = updateById(user);
        
        log.info("更新用户信息成功: userId={}", userId);
        return updateResult;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean realNameAuth(String realName, String idCardNumber, String idCardFront, String idCardBack) {
        // 检查登录状态
        YunkeSecurityUtil.checkLogin();
        
        Long userId = YunkeSecurityUtil.getCurrentUserId();
        log.info("实名认证: userId={}, realName={}, idCardNumber={}", userId, realName, 
                idCardNumber.substring(0, 6) + "****" + idCardNumber.substring(14));
        
        // 参数验证
        YunkeAssert.hasText(realName, YunkeResultCode.PARAM_ERROR, "真实姓名不能为空");
        YunkeAssert.hasText(idCardNumber, YunkeResultCode.PARAM_ERROR, "身份证号不能为空");
        YunkeAssert.hasText(idCardFront, YunkeResultCode.PARAM_ERROR, "身份证正面照片不能为空");
        YunkeAssert.hasText(idCardBack, YunkeResultCode.PARAM_ERROR, "身份证背面照片不能为空");
        
        // 验证身份证号格式
        String idCardRegex = "^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$";
        YunkeAssert.isTrue(idCardNumber.matches(idCardRegex), YunkeResultCode.PARAM_ERROR, "身份证号格式不正确");
        
        // 查询当前用户
        YunkeUser user = getById(userId);
        YunkeAssert.notNull(user, YunkeResultCode.USER_NOT_EXIST);
        
        // 检查是否已经实名认证
        if (user.getIsAuthentication() != null && user.getIsAuthentication() == 1) {
            log.warn("用户已经实名认证: userId={}", userId);
            throw new YunkeException(YunkeResultCode.USER_AUTH_EXIST, "您已经完成实名认证，无需重复认证");
        }
        
        // 检查身份证号是否已被使用
        YunkeUser existUser = userMapper.selectOne(
            new LambdaQueryWrapper<YunkeUser>()
                .eq(YunkeUser::getIdCardNumber, idCardNumber)
                .ne(YunkeUser::getId, userId)
        );
        YunkeAssert.isNull(existUser, YunkeResultCode.USER_AUTH_EXIST, "该身份证号已被其他用户使用");
        
        try {
            // TODO: 调用第三方身份验证API验证身份证信息
            // 这里模拟验证过程
            boolean verifyResult = mockIdCardVerification(realName, idCardNumber);
            if (!verifyResult) {
                log.warn("身份验证失败: userId={}, realName={}", userId, realName);
                throw new YunkeException(YunkeResultCode.USER_AUTH_FAIL, "身份验证失败，请检查姓名和身份证号是否匹配");
            }
            
            // 更新用户实名信息
            user.setRealName(realName);
            user.setIdCardNumber(idCardNumber);
            user.setIdCardFront(idCardFront);
            user.setIdCardBack(idCardBack);
            user.setIsAuthentication(1); // 已认证
            user.setUpdateTime(YunkeTimeUtil.timestampToLocalDateTime(System.currentTimeMillis()));
            
            boolean updateResult = updateById(user);
            
            if (updateResult) {
                log.info("实名认证成功: userId={}, realName={}", userId, realName);
                
                // TODO: 发送实名认证成功通知
                // smsService.sendAuthSuccessNotification(user.getPhone(), realName);
            }
            
            return updateResult;
            
        } catch (YunkeException e) {
            throw e;
        } catch (Exception e) {
            log.error("实名认证失败: userId={}, error={}", userId, e.getMessage(), e);
            throw new YunkeException(YunkeResultCode.SYSTEM_ERROR, "实名认证失败：" + e.getMessage());
        }
    }

    /**
     * 模拟身份证验证
     * 实际应该调用第三方身份验证服务
     */
    private boolean mockIdCardVerification(String realName, String idCardNumber) {
        // 模拟验证逻辑
        // 实际应该调用公安部身份验证接口或第三方服务
        log.info("模拟身份证验证: realName={}, idCardNumber={}", realName, 
                idCardNumber.substring(0, 6) + "****" + idCardNumber.substring(14));
        
        // 简单的模拟验证：姓名长度合理且身份证号不全为相同数字
        if (realName.length() < 2 || realName.length() > 10) {
            return false;
        }
        
        // 检查身份证号是否为测试号码（如：111111111111111111）
        boolean allSame = idCardNumber.chars().distinct().count() == 1;
        if (allSame) {
            return false;
        }
        
        // 模拟90%的成功率
        return Math.random() > 0.1;
    }

    // ==================== 个人中心模块实现 ====================

    @Override
    public YunkeUserCenterVo getUserCenter() {
        // 检查登录状态
        YunkeSecurityUtil.checkLogin();
        
        Long userId = YunkeSecurityUtil.getCurrentUserId();
        log.info("获取个人中心首页信息: userId={}", userId);
        
        YunkeUser user = getById(userId);
        YunkeAssert.notNull(user, YunkeResultCode.USER_NOT_EXIST);
        
        YunkeUserCenterVo centerVo = new YunkeUserCenterVo();
        
        // 用户基本信息
        YunkeUserCenterVo.UserInfo userInfo = new YunkeUserCenterVo.UserInfo();
        userInfo.setUserId(user.getId());
        userInfo.setNickname(user.getNickname());
        userInfo.setAvatar(user.getAvatar());
        userInfo.setGender(user.getGender());
        userInfo.setVipLevel(user.getVipLevel());
        userInfo.setIsAuth(user.getIsAuthentication() == 1);
        userInfo.setBio(user.getSignature());
        userInfo.setRegisterTime(YunkeTimeUtil.localDateTimeToTimestamp(user.getCreateTime()));
        centerVo.setUserInfo(userInfo);
        
        // 统计数据
        centerVo.setStatistics(getUserStatistics());
        
        // 财务信息
        YunkeUserCenterVo.FinanceInfo finance = new YunkeUserCenterVo.FinanceInfo();
        finance.setBalance(user.getBalance());
        finance.setTotalIncome(BigDecimal.ZERO); // TODO: 从订单表统计
        finance.setTotalExpense(BigDecimal.ZERO); // TODO: 从订单表统计
        finance.setPendingAmount(BigDecimal.ZERO); // TODO: 从订单表统计
        finance.setWithdrawableAmount(user.getBalance());
        centerVo.setFinance(finance);
        
        // 等级信息
        YunkeUserCenterVo.LevelInfo level = new YunkeUserCenterVo.LevelInfo();
        level.setCurrentLevel(user.getUserLevel());
        level.setCurrentExp(user.getExperience());
        level.setNextLevelExp(1000); // TODO: 从等级表查询
        level.setLevelName("普通用户"); // TODO: 从等级表查询
        level.setLevelIcon("");
        level.setProgressPercent(Math.min(100, (user.getExperience() * 100) / 1000));
        centerVo.setLevel(level);
        
        // 邀请信息
        centerVo.setInvite(getInviteInfo());
        
        // 功能菜单
        List<YunkeUserCenterVo.MenuItem> menuItems = buildMenuItems();
        centerVo.setMenuItems(menuItems);
        
        log.info("获取个人中心首页信息成功: userId={}", userId);
        return centerVo;
    }

    @Override
    public YunkeUserInfoVo getUserProfile(Long userId) {
        // 如果未指定用户ID，则查询当前用户
        if (userId == null) {
            YunkeSecurityUtil.checkLogin();
            userId = YunkeSecurityUtil.getCurrentUserId();
        }
        
        log.info("获取用户详细信息: userId={}", userId);
        
        YunkeUser user = getById(userId);
        YunkeAssert.notNull(user, YunkeResultCode.USER_NOT_EXIST);
        
        return convertToUserInfoVo(user);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean editProfile(YunkeUserProfileDto profileDto) {
        // 检查登录状态
        YunkeSecurityUtil.checkLogin();
        
        Long userId = YunkeSecurityUtil.getCurrentUserId();
        log.info("编辑个人信息: userId={}", userId);
        
        YunkeUser user = getById(userId);
        YunkeAssert.notNull(user, YunkeResultCode.USER_NOT_EXIST);
        
        // 更新用户信息
        if (StringUtils.hasText(profileDto.getNickname())) {
            user.setNickname(profileDto.getNickname());
        }
        if (StringUtils.hasText(profileDto.getAvatar())) {
            user.setAvatar(profileDto.getAvatar());
        }
        if (profileDto.getGender() != null) {
            user.setGender(profileDto.getGender());
        }
        if (StringUtils.hasText(profileDto.getBio())) {
            user.setSignature(profileDto.getBio());
        }
        // TODO: 处理其他字段（生日、职业、兴趣等）
        
        user.setUpdateTime(YunkeTimeUtil.timestampToLocalDateTime(System.currentTimeMillis()));
        boolean result = updateById(user);
        
        log.info("编辑个人信息成功: userId={}", userId);
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean followUser(Long followUserId) {
        // 检查登录状态
        YunkeSecurityUtil.checkLogin();
        
        Long userId = YunkeSecurityUtil.getCurrentUserId();
        log.info("关注/取消关注用户: userId={}, followUserId={}", userId, followUserId);
        
        // 参数验证
        YunkeAssert.notNull(followUserId, YunkeResultCode.PARAM_ERROR, "被关注用户ID不能为空");
        YunkeAssert.isFalse(userId.equals(followUserId), YunkeResultCode.PARAM_ERROR, "不能关注自己");
        
        // 检查被关注用户是否存在
        YunkeUser followUser = getById(followUserId);
        YunkeAssert.notNull(followUser, YunkeResultCode.USER_NOT_EXIST, "被关注用户不存在");
        
        // TODO: 实现关注逻辑，需要关注表支持
        log.info("关注功能待实现: userId={}, followUserId={}", userId, followUserId);
        return true;
    }

    @Override
    public Page<YunkeUserInfoVo> getFollowList(Long current, Long size) {
        // 检查登录状态
        YunkeSecurityUtil.checkLogin();
        
        Long userId = YunkeSecurityUtil.getCurrentUserId();
        log.info("获取关注列表: userId={}, current={}, size={}", userId, current, size);
        
        // TODO: 实现关注列表查询
        Page<YunkeUserInfoVo> result = new Page<>(current, size);
        result.setTotal(0L);
        result.setRecords(new ArrayList<>());
        
        return result;
    }

    @Override
    public Page<YunkeUserInfoVo> getFansList(Long current, Long size) {
        // 检查登录状态
        YunkeSecurityUtil.checkLogin();
        
        Long userId = YunkeSecurityUtil.getCurrentUserId();
        log.info("获取粉丝列表: userId={}, current={}, size={}", userId, current, size);
        
        // TODO: 实现粉丝列表查询
        Page<YunkeUserInfoVo> result = new Page<>(current, size);
        result.setTotal(0L);
        result.setRecords(new ArrayList<>());
        
        return result;
    }

    @Override
    public YunkeUserCenterVo.StatisticsInfo getUserStatistics() {
        // 检查登录状态
        YunkeSecurityUtil.checkLogin();
        
        Long userId = YunkeSecurityUtil.getCurrentUserId();
        log.info("获取用户统计数据: userId={}", userId);
        
        YunkeUserCenterVo.StatisticsInfo statistics = new YunkeUserCenterVo.StatisticsInfo();
        statistics.setFollowCount(0); // TODO: 从关注表统计
        statistics.setFansCount(0); // TODO: 从关注表统计
        statistics.setLikeCount(0); // TODO: 从点赞表统计
        statistics.setCircleCount(0); // TODO: 从动态表统计
        statistics.setDaziCount(0); // TODO: 从搭子表统计
        statistics.setServiceCount(0); // TODO: 从服务表统计
        
        return statistics;
    }

    @Override
    public YunkeUserCenterVo.InviteInfo getInviteInfo() {
        // 检查登录状态
        YunkeSecurityUtil.checkLogin();
        
        Long userId = YunkeSecurityUtil.getCurrentUserId();
        log.info("获取邀请信息: userId={}", userId);
        
        YunkeUser user = getById(userId);
        
        YunkeUserCenterVo.InviteInfo invite = new YunkeUserCenterVo.InviteInfo();
        invite.setInviteCode(user.getInviteCode());
        invite.setInviteUrl("https://yunke.com/invite?code=" + user.getInviteCode());
        invite.setInviteCount(0); // TODO: 统计邀请人数
        invite.setTotalCommission(BigDecimal.ZERO); // TODO: 统计佣金
        
        return invite;
    }

    @Override
    public YunkeUserInfoVo getOtherUserProfile(Long userId) {
        log.info("查看其他用户信息: userId={}", userId);
        
        YunkeAssert.notNull(userId, YunkeResultCode.PARAM_ERROR, "用户ID不能为空");
        
        YunkeUser user = getById(userId);
        YunkeAssert.notNull(user, YunkeResultCode.USER_NOT_EXIST);
        
        // TODO: 检查隐私设置，决定返回哪些信息
        return convertToUserInfoVo(user);
    }

    @Override
    public boolean updateSystemSettings(String settingKey, String settingValue) {
        // 检查登录状态
        YunkeSecurityUtil.checkLogin();
        
        Long userId = YunkeSecurityUtil.getCurrentUserId();
        log.info("系统设置: userId={}, key={}, value={}", userId, settingKey, settingValue);
        
        // TODO: 实现系统设置功能
        return true;
    }

    @Override
    public boolean submitFeedback(String content, String images, String contact) {
        // 检查登录状态
        YunkeSecurityUtil.checkLogin();
        
        Long userId = YunkeSecurityUtil.getCurrentUserId();
        log.info("提交意见反馈: userId={}, content={}", userId, content);
        
        // TODO: 实现意见反馈功能，保存到反馈表
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean uploadAvatar(String avatarUrl) {
        // 检查登录状态
        YunkeSecurityUtil.checkLogin();
        
        Long userId = YunkeSecurityUtil.getCurrentUserId();
        log.info("上传头像: userId={}, avatarUrl={}", userId, avatarUrl);
        
        YunkeAssert.hasText(avatarUrl, YunkeResultCode.PARAM_ERROR, "头像URL不能为空");
        
        YunkeUser user = getById(userId);
        YunkeAssert.notNull(user, YunkeResultCode.USER_NOT_EXIST);
        
        user.setAvatar(avatarUrl);
        user.setUpdateTime(YunkeTimeUtil.timestampToLocalDateTime(System.currentTimeMillis()));
        
        boolean result = updateById(user);
        log.info("上传头像成功: userId={}", userId);
        return result;
    }

    @Override
    public Object getAuthStatus() {
        // 检查登录状态
        YunkeSecurityUtil.checkLogin();
        
        Long userId = YunkeSecurityUtil.getCurrentUserId();
        log.info("获取用户认证状态: userId={}", userId);
        
        YunkeUser user = getById(userId);
        
        Map<String, Object> authStatus = new HashMap<>();
        authStatus.put("isPhoneAuth", StringUtils.hasText(user.getPhone()));
        authStatus.put("isRealNameAuth", user.getIsAuthentication() == 1);
        authStatus.put("authLevel", user.getIsAuth());
        authStatus.put("realName", user.getRealName());
        
        return authStatus;
    }

    @Override
    public Page<Object> getFavoriteList(Long current, Long size, Integer type) {
        // 检查登录状态
        YunkeSecurityUtil.checkLogin();
        
        Long userId = YunkeSecurityUtil.getCurrentUserId();
        log.info("获取收藏列表: userId={}, type={}", userId, type);
        
        // TODO: 实现收藏列表查询
        Page<Object> result = new Page<>(current, size);
        result.setTotal(0L);
        result.setRecords(new ArrayList<>());
        
        return result;
    }

    @Override
    public boolean updatePrivacySettings(String settingType, String settingValue) {
        // 检查登录状态
        YunkeSecurityUtil.checkLogin();
        
        Long userId = YunkeSecurityUtil.getCurrentUserId();
        log.info("隐私设置: userId={}, type={}, value={}", userId, settingType, settingValue);
        
        // TODO: 实现隐私设置功能
        return true;
    }

    /**
     * 构建功能菜单
     */
    private List<YunkeUserCenterVo.MenuItem> buildMenuItems() {
        List<YunkeUserCenterVo.MenuItem> menuItems = new ArrayList<>();
        
        // 我的搭子
        YunkeUserCenterVo.MenuItem daziItem = new YunkeUserCenterVo.MenuItem();
        daziItem.setId("my_dazi");
        daziItem.setName("我的搭子");
        daziItem.setIcon("icon-dazi");
        daziItem.setUrl("/my/dazi");
        daziItem.setBadgeCount(0);
        daziItem.setVisible(true);
        menuItems.add(daziItem);
        
        // 我的动态
        YunkeUserCenterVo.MenuItem circleItem = new YunkeUserCenterVo.MenuItem();
        circleItem.setId("my_circle");
        circleItem.setName("我的动态");
        circleItem.setIcon("icon-circle");
        circleItem.setUrl("/my/circle");
        circleItem.setBadgeCount(0);
        circleItem.setVisible(true);
        menuItems.add(circleItem);
        
        // 钱包
        YunkeUserCenterVo.MenuItem walletItem = new YunkeUserCenterVo.MenuItem();
        walletItem.setId("wallet");
        walletItem.setName("我的钱包");
        walletItem.setIcon("icon-wallet");
        walletItem.setUrl("/wallet");
        walletItem.setBadgeCount(0);
        walletItem.setVisible(true);
        menuItems.add(walletItem);
        
        // 设置
        YunkeUserCenterVo.MenuItem settingsItem = new YunkeUserCenterVo.MenuItem();
        settingsItem.setId("settings");
        settingsItem.setName("设置");
        settingsItem.setIcon("icon-settings");
        settingsItem.setUrl("/settings");
        settingsItem.setBadgeCount(0);
        settingsItem.setVisible(true);
        menuItems.add(settingsItem);
        
        return menuItems;
    }

    /**
     * 转换用户实体为VO
     */
    private YunkeUserInfoVo convertToUserInfoVo(YunkeUser user) {
        YunkeUserInfoVo userInfoVo = new YunkeUserInfoVo();
        userInfoVo.setId(user.getId());
        userInfoVo.setUsername(user.getUsername());
        userInfoVo.setPhone(user.getPhone());
        userInfoVo.setNickname(user.getNickname());
        userInfoVo.setAvatar(user.getAvatar());
        userInfoVo.setGender(user.getGender());
        userInfoVo.setAge(user.getAge());
        userInfoVo.setSignature(user.getSignature());
        userInfoVo.setVipLevel(user.getVipLevel());
        userInfoVo.setInviteCode(user.getInviteCode());
        userInfoVo.setIsAuth(user.getIsAuth());
        userInfoVo.setCreateTime(user.getCreateTime());
        userInfoVo.setLastLoginTime(YunkeTimeUtil.timestampToLocalDateTime(user.getLastLoginTime()));
        
        return userInfoVo;
    }
}